package com.cangxuan.backend.filter;

import com.cangxuan.backend.entity.User;
import com.cangxuan.backend.utils.ViewUtils;
import com.cangxuan.backend.wrapper.BodyReaderHttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * 我的身份认证过滤器
 */
@Slf4j
@Component
public class MyAuthorizationFilter extends OncePerRequestFilter {

    RedisTemplate redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        log.info("进入MyAuthorizationFilter了...");

        //从请求头中获取设备编号
        String deviceId = request.getHeader("Authorization");
        if (deviceId != null) {
            //根据deviceId从redis中获取对应用户信息
            User user = (User) redisTemplate.opsForValue().getAndExpire("phone-deviceId-" + deviceId, 10, TimeUnit.DAYS);
            if (user == null) {
                ViewUtils.print(response, 401, "身份认证失败，请登录");
                return;
            }
            log.info("用户已登录.......");
            //创建当前用户权限集合
            List<GrantedAuthority> authorities = new ArrayList<>();
            //如果用户已实名，则拥有VIP权限
            if (user.getRealName() != null) {
                authorities.add(new SimpleGrantedAuthority("vip"));
            }
            log.info("当前用户权限集合：" + Arrays.toString(authorities.toArray()));

            //创建身份认证信息对象
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(user, deviceId, authorities);
            //将上面这个对象存储到Security上下文对象中，之后Security框架才认为本次请求的身份是经过认证的
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }

        BodyReaderHttpServletRequestWrapper bodyReaderHttpServletRequestWrapper;
        try {
            bodyReaderHttpServletRequestWrapper = new BodyReaderHttpServletRequestWrapper(request);
        } catch (Exception e) {
            ViewUtils.print(response, 400, "参数检验失败");
            e.printStackTrace();
            return;
        }

        filterChain.doFilter(bodyReaderHttpServletRequestWrapper, response);
    }

}
